<?php
// +----------------------------------------------------------------------
// | ThinkSNS
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://www.thinksns.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: Daniel Yang <desheng.young@gmail.com>
// +----------------------------------------------------------------------
//

/**
 +------------------------------------------------------------------------------
 * RssGenerateService RSS生成服务
 * 实现对内容的RSS格式生成
 * 为各个应用的RSS订阅提供支持
 +------------------------------------------------------------------------------
 * @category	addons
 * @package		addons
 * @subpackage  services
 * @author		Daniel Yang <desheng.young@gmail.com>
 * @version		$Id$
 +------------------------------------------------------------------------------
 */

class RssGenerateService extends Service {
	private $version;
	private $rsspath;
	private $tableName;
	
	public function __construct() {
		$this->init();
	}
	
	public function setVersion($version) {
	    $this->version = $version;
	}
	public function getVersion() {
	    return $this->version;
	}
	public function setRssPath($path) {
	    $this->rsspath = $path;
	}
	public function getRssPath() {
	    return $this->rsspath;
	}
	public function setTableName($tableName) {
		$this->tableName = $tableName;
	}
	
	public function init() {
		include_once(SITE_PATH.'/addons/libs/RSS/FeedWriter/FeedWriter.php');
		include_once(SITE_PATH.'/addons/libs/RSS/FeedWriter/FeedItem.php');
		$this->version = 'RSS 2.0';
		$this->rsspath = DATA_PATH;
		$this->tableName = 'x_rss';
	}
	
	//添加一个RSS源
	public function add($map, $replace = false) {
		/*
        //需要提供的参数
	    $map['app']   = 'wiki';
	    $map['model'] = 'Wiki';
	    $map['param'] = 56;
		*/
	    
	    //校验合法性
	    if(empty($map['app']) || empty($map['model'])) {
	        return array('error'=> true, 'info' => 'app/model不能为空');
	    }
	    $map['method'] = empty($map['method']) ? 'generateRss' : $map['method'];
	    $data = D($map['model'], $map['app'])->$map['method']($map['param']);
	    //检查channel
	    if(empty($data['name']) || empty($data['title']) || empty($data['link']) || empty($data['description'])) {
	        return array('error'=> true, 'info' => 'channel的name/title/link/description不能为空');
	    }
	    //检查item
	    foreach($data['items'] as $v) {
	        if(empty($v['title']) || empty($v['link']) || empty($v['description'])) {
    	        return array('error'=> true, 'info' => 'item的title/link/description不能为空');
    	    }
    	    //检查item的enclosure
    	    if( !empty($v['enclosure']) && (empty($v['enclosure']['length']) || empty($v['enclosure']['type']) || empty($v['enclosure']['url'])) ) {
    	        return array('error'=> true, 'info' => 'enclosure的length/type/url不能为空');
    	    }
	    }

	    //保存数据库
	    $rss = array();
	    $rss['name']    = $data['name'];
	    $rss['app']     = $map['app'];
	    $rss['model']   = $map['model'];
	    $rss['method']  = $map['method'];
	    $rss['param']   = $map['param'];
		$model = M($this->tableName);
		unset($map);
		$map['name'] = $data['name'];
		if($replace == false) {
			if($model->where($map)->limit(1)->findAll()) {
				return array('error' => true, 'info' => 'duplicate name.');
			}
		}else {
			$model->where($map)->delete();
		}
	    if(!$model->add($rss)) {
	        return array('error'=> true, 'info' => 'failed to insert into db');
	    }

        //生成rss.xml文件
	    $content = $this->generateRssXml($data);
	    $temp = $this->generateRssFile($data['name'], $content);
	    if(!empty($temp) && $temp['error'] == true) {
	        return $temp;
	    }
	    
	    return array('error'=> false, 'info' => 'success');
	}
	
	//更新所有RSS源（由计划任务执行）
	public function refresh() {
	    $res = M($this->tableName)->findAll();
        foreach($res as $k => $v) {
            $data = D($v['model'], $v['app'])->$v['method']($v['param']);
			$content = $this->generateRssXml($data);
			$this->generateRssFile($data['name'], $content);
			unset($content);
			unset($data);
        }
	}
	
	//生成RSS xml
	public function generateRssXml($data) {
	    $feed = new FeedWriter($this->version);
	    $this->_setChannel(&$feed, $data);
	    $this->_setItem(&$feed, $data);
	    $res = $feed->genarateFeed();
		return $res;
	}
	
	//生成RSS文件
	public function generateRssFile($name, $content) {
	    $filename = $this->rsspath . $name . '.xml';
		$handle = fopen($filename, 'w');
		if($handle == false) {
		    return array('error' => true, 'info' => 'failed to open file.');
		}
		fwrite($handle, $content);
		fclose($handle);
	}
	
	//设置频道
	protected function _setChannel($feed, $data) {
	  	foreach($data as $k => $v) {
	  	    switch($k) {
	  	        case 'name':
	  	            ;
	  	            break;
	  	        case 'items':
	  	            ;
	  	            break;
	  	        case 'lastBuildDate':
	  	            $feed->setChannelElement($k, date(DATE_RSS, $v));
	  	            break;
	  	        case 'pubDate':
	  	            $feed->setChannelElement($k, date(DATE_RSS, $v));
	  	            break;
	  	        case 'image':
	  	            $feed->setImage($data['title'], $data['link'], $v);
	  	            break;
	  	        default:
	  	            $feed->setChannelElement($k, $v);
	  	    }
	  	} // END foreach {}
	}
	
	//设置item
	protected function _setItem($feed, $data) {
		foreach($data['items'] as $value) {
		    $item = $feed->createNewItem();
		    foreach($value as $k => $v) {
    		    switch($k) {
    		        case 'pubDate':
    		            $item->setDate($v);
    		            break;
    		        case 'link':
    		            $item->setLink($v);
    		            break;
    		        case 'enclosure':
    		            $item->setEncloser($v['url'], $v['length'], $v['type']);
    		            break;
    		        case 'description':
    		            $item->setDescription($v);
    		            break;
    		        case 'guid':
    		            $item->addElement($k, $v, array('isPermaLink'=>'true'));
    		            break;
    		        default:
    		            $item->addElement($k, $v);
    		    }
    		} // END foreach {}
		    $feed->addItem($item);
		} // END foreach {}
	}
	
	public function run() {
		
	}
	
	public function _start() {
		
	}
	
	public function _stop() {
		
	}
	
	public function _install() {
		
	}
	
	public function _uninstall() {
		
	}
}
?>